#ifndef STREAMIO_H
#define STREAMIO_H

#include <length.h>
typedef _ptlong _str;

#define u8   unsigned char
#define u32  unsigned int

#define _______STRFUNC_______(strType,funcName)             strType##_##funcName
#define _____STRFUNC_____(x,funcName)              _______STRFUNC_______(x,funcName)
#define ____STRFUNC____(x,funcName)              _____STRFUNC_____(x,funcName)
#define ___STRFUNC___(x,funcName)              ____STRFUNC____(x,funcName)
#define __STRFUNC__(x,funcName)              ___STRFUNC___(x,funcName)
#define _STRFUNC_(x,funcName)              __STRFUNC__(x,funcName)
#define STRFUNC_(funcName)		_STRFUNC_(strType,funcName)

#include "struct_fileStream.h"
#include "virtualStream.h"
/*
#define _FULLNAME(x) __FULLNAME(x)
#define __FULLNAME(x) x##FULLNAME

#define _fstr struct __FULLNAME(_fstr)*
#define _vstr struct __FULLNAME(_vstr)*
*/


#define __DEFAULT__PUBLIC__STRTYPE  _str
#define _dfps  __DEFAULT__PUBLIC__STRTYPE



//MountStream_IO
#include <structure.h>
//#include "model_mountStream_IO.h"

//Extended Stream_IO
#define ConvertStream(streamfrom,streamto) do\
  {					   \
    _dfps pubs = CreateStream();	   \
    ConvertToPub(streamfrom,pubs,INFINITE,0);	\
    ConvertToPrv(pubs,streamto,INFINITE,0);	\
  }while(0)

#define __DSope(strType) strType##_##_dsop
#define _dsope(strType)  __DSope(strType)
#define STRFUNC(x)       x


template<typename A,typename B>
static _ptlong STRFUNC(MountStream)(A stream,B root)
{
  return _MOUNT(stream,root);
}

template<typename A,typename B>
static _ptlong STRFUNC(UnmountStream)(A stream,B root)
{
  return _UNMOUNT(stream,root);
}
char* GetStreamPath(_ptlong mstream);
_ptlong GetStream(char* path, _ptlong root = 0);


//template<typename A>
//extern A STRFUNC(CreateStream)(A (*allocMemory)(_ptlong));
//Have to explict declare
#define _explict_CreateStream(x) x STRFUNC(CreateStream)(x (*allocMemory)(_ptlong))
_explict_CreateStream(_str);
_explict_CreateStream(_fstr);
_explict_CreateStream(_vstr);

template<typename A>
extern A STRFUNC(WriteStream) (A stream, u8* input, _length num, _length offset);
template<typename A>
extern A STRFUNC(ReadStream)  (A stream, u8* output,  _length num, _length offset);

template<typename A>
extern _ptlong STRFUNC(ConvertToPub) (A from, _dfps to, _length num, _length offset);
template<typename A>
extern _ptlong STRFUNC(ConvertToPrv) (_dfps from, A to, _length num, _length offset);
template<typename A>
extern A STRFUNC(SeekStream)  (A stream,  _length num);
template<typename A>
extern _length STRFUNC(GetLengthStream)(A of);

template<typename A,typename B>
extern _ptlong STRFUNC(DelegateStream)(A stream,_pcb* pro, B* operations);

template<typename A>
_ptlong STRFUNC(EndStream)(A target);

#endif
